package cn.com.bluemoon.daps.sync.service.impl;

import cn.com.bluemoon.daps.common.domain.UserInfoHolder;
import cn.com.bluemoon.daps.common.enums.SyncStatus;
import cn.com.bluemoon.daps.common.enums.SyncToEnv;
import cn.com.bluemoon.daps.sync.core.sync.GlobalConfig;
import cn.com.bluemoon.daps.sync.entity.DapSyncProdEnvTaskDetail;
import cn.com.bluemoon.daps.sync.mapper.DapSyncProdEnvTaskDetailMapper;
import cn.com.bluemoon.daps.sync.service.DapSyncProdEnvTaskDetailService;
import cn.com.bluemoon.daps.sync.vo.syncmanage.SyncTableEnvAndRealDdlParam;
import cn.com.bluemoon.daps.sync.vo.syncmanage.SyncTableParam;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * <p>
 * 发布同步单号数据任务-明细表 服务实现类
 * </p>
 *
 * @author admin
 * @since 2021-06-17
 */
@Slf4j
@Service
public class DapSyncProdEnvTaskDetailServiceImpl extends ServiceImpl<DapSyncProdEnvTaskDetailMapper, DapSyncProdEnvTaskDetail>
        implements DapSyncProdEnvTaskDetailService {


    /**
     * 根据任务id获取任务明细列表
     *
     * @param taskId 任务id
     * @return 列表
     */
    @Override
    public List<DapSyncProdEnvTaskDetail> findTaskDetailsByTaskId(String taskId) {
        LambdaQueryWrapper<DapSyncProdEnvTaskDetail> eq = bmLambdaQuery().eq(DapSyncProdEnvTaskDetail::getTaskId, taskId)
                .orderByAsc(DapSyncProdEnvTaskDetail::getCreateTime);
        return list(eq);
    }

    /**
     * 获取模型单号待处理任务ddl列表
     *
     * @param taskId       任务
     * @param globalConfig 全局信息
     * @return list
     */
    @Override
    public List<DapSyncProdEnvTaskDetail> findSyncTasks(String taskId, GlobalConfig globalConfig) {
        // 增加逻辑 每次执行都是拿那些非已同步的脚本去跑，因为已同步的不用再次同步了
        List<DapSyncProdEnvTaskDetail> taskDetails = new ArrayList<>();
        LambdaQueryWrapper<DapSyncProdEnvTaskDetail> eq;
        // 2021/7/1 获取同步数据中，要是为走 isSyncSandboxMock的情况下，都是那全量ddl进行沙箱环境执行
        if (SyncToEnv.PRE_PROD.equals(globalConfig.getSyncToEnv())) {
            eq = bmLambdaQuery()
                    .eq(DapSyncProdEnvTaskDetail::getTaskId, taskId)
                    .ne(DapSyncProdEnvTaskDetail::getPreProdScriptStatus, SyncStatus.SYNC_DONE)
                    .orderByAsc(DapSyncProdEnvTaskDetail::getCreateTime);
            taskDetails = list(eq);
        }
        if (SyncToEnv.PROD.equals(globalConfig.getSyncToEnv())) {
            eq = bmLambdaQuery()
                    .eq(DapSyncProdEnvTaskDetail::getTaskId, taskId)
                    .ne(DapSyncProdEnvTaskDetail::getProdScriptStatus, SyncStatus.SYNC_DONE)
                    .orderByAsc(DapSyncProdEnvTaskDetail::getCreateTime);
            taskDetails = list(eq);
        }
        return taskDetails;
    }

    @Override
    public boolean updateStatusByParam(SyncTableEnvAndRealDdlParam param, SyncToEnv syncToEnv, UserInfoHolder.UserInfo userInfo) {
        LambdaUpdateWrapper<DapSyncProdEnvTaskDetail> updateTableSyncStatus = bmLambdaUpdate().eq(DapSyncProdEnvTaskDetail::getModelId, param.getModelId())
                .eq(DapSyncProdEnvTaskDetail::getId, param.getTaskDetailId())
                .set(SyncToEnv.PRE_PROD.equals(syncToEnv), DapSyncProdEnvTaskDetail::getPreProdScriptStatus, SyncStatus.SYNC_DONE)
                .set(SyncToEnv.PROD.equals(syncToEnv), DapSyncProdEnvTaskDetail::getProdScriptStatus, SyncStatus.SYNC_DONE)
                .set(SyncToEnv.PRE_PROD.equals(syncToEnv), DapSyncProdEnvTaskDetail::getRealSyncPreProdDdl, param.getRealDdl())
                .set(SyncToEnv.PROD.equals(syncToEnv), DapSyncProdEnvTaskDetail::getRealSyncProdDdl, param.getRealDdl())
                .set(DapSyncProdEnvTaskDetail::getDbaManageBy, userInfo.getAccount())
                .set(DapSyncProdEnvTaskDetail::getNeedDba, Boolean.TRUE)
                .set(DapSyncProdEnvTaskDetail::getSandboxSyncFail, Boolean.FALSE)// 更改状态成功后把执行在沙箱失败的置为false，为了发布同步查看脚本能显示为已执行
                .set(DapSyncProdEnvTaskDetail::getDbaManageTime, LocalDateTime.now());
        boolean update = update(updateTableSyncStatus);
        log.info("更新taskId={},env:{}, ddl同步语句状态,status:{}", param.getTaskDetailId(), syncToEnv, update);
        return update;
    }

    @Override
    public Optional<DapSyncProdEnvTaskDetail> queryOneByParam(SyncTableParam param) {
        LambdaQueryWrapper<DapSyncProdEnvTaskDetail> eq = bmLambdaQuery().eq(DapSyncProdEnvTaskDetail::getModelId, param.getModelId())
                .eq(DapSyncProdEnvTaskDetail::getTaskId, param.getTaskId())
                .eq(DapSyncProdEnvTaskDetail::getTableId, param.getTaskTableId())
                .orderByDesc(DapSyncProdEnvTaskDetail::getId)
                .last("limit 1");
        return Optional.ofNullable(getOne(eq));
    }

    @Override
    public void updateSyncStatusByTaskIdAndSyncEnvAndSyncStatus(String taskId, SyncToEnv syncToEnv, SyncStatus syncWait) {
        LambdaUpdateWrapper<DapSyncProdEnvTaskDetail> updateSyncStatusByTaskId = bmLambdaUpdate().eq(DapSyncProdEnvTaskDetail::getTaskId, taskId)
                .set(SyncStatus.SYNC_ERROR.equals(syncWait), DapSyncProdEnvTaskDetail::getNeedDba, Boolean.TRUE)
                .set(SyncToEnv.PRE_PROD.equals(syncToEnv), DapSyncProdEnvTaskDetail::getPreProdScriptStatus, syncWait)
                .set(SyncToEnv.PROD.equals(syncToEnv), DapSyncProdEnvTaskDetail::getProdScriptStatus, syncWait);
        update(updateSyncStatusByTaskId);
    }

    @Override
    public void updateTableSyncFailOnSandbox(String taskId, boolean sandboxSyncFail) {
        LambdaUpdateWrapper<DapSyncProdEnvTaskDetail> updateSandboxSyncFailByTaskId = bmLambdaUpdate()
                .eq(DapSyncProdEnvTaskDetail::getTaskId, taskId)
                .set(DapSyncProdEnvTaskDetail::getSandboxSyncFail, sandboxSyncFail);
        boolean update = update(updateSandboxSyncFailByTaskId);
        log.info("更改任务id={}，状态为：{}，情况：{}", taskId, sandboxSyncFail, update);
    }

    @Override
    public void updateSyncLogContent(String taskId, SyncToEnv syncToEnv, String logContent) {
        LambdaQueryWrapper<DapSyncProdEnvTaskDetail> eq = bmLambdaQuery()
                .eq(DapSyncProdEnvTaskDetail::getTaskId, taskId);
        List<DapSyncProdEnvTaskDetail> taskDetails = list(eq);
        if (SyncToEnv.PRE_PROD.equals(syncToEnv)) {
            for (DapSyncProdEnvTaskDetail each : taskDetails) {
                each.setPreProdSyncLog(each.getPreProdSyncLog() + "\n" + logContent);
            }
        } else if (SyncToEnv.PROD.equals(syncToEnv)) {
            for (DapSyncProdEnvTaskDetail each : taskDetails) {
                each.setProdSyncLog(each.getProdSyncLog() + "\n" + logContent);
            }
        }
        updateBatchById(taskDetails);
    }


}
